/**
 * @file CRhoBrentPvmAlg.hpp Deklarácia triedy CRhoBrentPvmAlg.
 *
 * @author Martin Kosorinský.
 * @date 10.10.2009.
 */

#ifndef CRHOBRENTPVMALG_HEADER
#define CRHOBRENTPVMALG_HEADER

#include "CRhoBrentAlg.hpp"
#include "CPvmSlaveCommands.hpp"

/**
 * @brief PVM implementácia Brentovho algoritmu.
 * Trieda Brentovho algoritmu s pridanou podporou @c PVM a úpravami potrebnými pre zabezpečenie paralelného
 * behu. Trieda rozširuje #CRhoBrentAlg prvky @c PVM komunikácie - zasielanie @a distinguished bodov
 * rodičovskému procesu.
 */
class CRhoBrentPvmAlg : public CRhoBrentAlg, public CPvmSlaveCommands {
private:
    /**
     * @brief Unikátne @c PVM identifikačné číslo rodiča výpočtového uzla (parent TID).
     * Uložená hodnota slúži ako kód adresáta pre odosielané správy, a ako kód odosielateľa
     * pre príjem sprav. Počiatočná hodnota je -1.
     * @warning Hodnotu je nevyhnutné nastaviť na @c pvm_parent() pred využívaním komunikačných procedúr.
     */
    static int pTID;
public:
    /**
     * @brief Hlavná metóda spúšťajúca výpočet diskrétneho logaritmu.
     * Metóda pracuje na základe vopred inicializovaných nastavení kontextu, medzi ktoré patria parametre
     * krivky, generátor a bod, ktorého diskrétny logaritmus hľadáme.
     * Algoritmus počíta pseudonáhodnú postupnosť (deterministickú) bodov na eliptickej krivke, až kým
     * za pomoci Brentovho algoritmu neodhalí cyklus, resp. kolíziu bodov. Následne je zo získaných
     * koeficientov kolízie vypočítaný hľadaný diskrétny logaritmus.
     * @param[in] ptid PVM identifikátor rodičovského uzla (adresa odosielaných správ).
     * @param[in] dist Parameter filtračnej funkcie (distinguished point), pomocou 2^dist modulujeme, viz. #isDistinguished. Parameter
     * predstavuje počet 0 na konci afínnej súradnice bodu, ktoré musí obsahovať, aby prešiel filtráciou.
     * @param[out] vysledok Premenná typu big, do ktorej bude uložený výsledok v prípade úspechy výpočtu.
     * Pamäť musí byť vopred alokovaná!
     * @warning V prípade neúspechu výpočtu obsahuje premenná @a výsledok nedefinovanú hodnotu.
     * @warning Funkcia nie je thread-safe.
     * @return Vráti TRUE v prípade úspechu výpočtu, v opačnom prípade vráti FALSE.
     */
    static bool computeLogarithm(int ptid, int dist, big vysledok);
    /**
     * @brief Funkcia testujúca bod eliptickej krivky (distinguished point).
     * Funkcia filtruje tzv. distinguished body eliptickej krivky. Ako test je využívaná jednoduchá
     * modulárna operácia na druhej (y) súradnici bodu. Operácia je parametrizovaná hodnotou @a distMod
     * a navrhnutá tak aby bola čo najefektívnejšia. Preto by @a distMod mala byť mocnina 2.
     * V prípade, že bod prejde testom, informácia o tom vrátane príslušných parametrov je odoslaná
     * prostredníctvom PVM rodičovi.
     * @note Bod v nekonečne (infinity point) je ignorovaný a nikdy nemôže byť považovaný za význačný.
     * @param[in] X  je bod na eliptickej krivke typu epoint*, ktorý testujeme.
     * @param[in] a predstavuje exponent pri bode G (generátor)
     * @param[in] b predstavuje exponent pri bode H (bod s neznámym DL).
     * @param[in] distMod hodnota, ktorou modulujeme súradnicu pri filtrácii.
     * @warning Funkcia nie je thread-safe (kvôli efektivite).
     * @return Vráti TRUE, ak bod @a X je distinguished, v opačnom prípade vráti FALSE.
     */
    static bool isDistinguished(epoint * X, big a, big b, big distMod);
};
#endif /* CRHOBRENTPVMALG_HEADER */
